package org.jpass.dc.view.upload;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.RequestContext;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest;

public class MyMultiPartRequest extends JakartaMultiPartRequest {

	private static final Log log = LogFactory.getLog(MyMultiPartRequest.class);

	@SuppressWarnings("unchecked")
	@Override
	public void parse(HttpServletRequest servletRequest, String saveDir)
			throws IOException {
		DiskFileItemFactory fac = new DiskFileItemFactory();
		fac.setSizeThreshold(1024 * 1024);
		if (saveDir != null) {
			fac.setRepository(new File(saveDir));
		}

		// Parse the request
		ServletFileUpload upload = new ServletFileUpload(fac);
		// 最大上传限制
		upload.setSizeMax(maxSize);
		// 设置监听器监听上传进度 
		MyProgressListener p = new MyProgressListener(servletRequest);
		upload.setProgressListener(p);
		servletRequest.setAttribute("maxSize", maxSize);
		List<FileItem> items = null;

		try {
			items = (List<FileItem>) upload
					.parseRequest(createRequestContext(servletRequest));
			for (FileItem fileItem : items) {
				String itemFieldName = fileItem.getFieldName();
				if (log.isDebugEnabled()) {
					log.debug("Found item " + itemFieldName);
				}
				if (fileItem.isFormField()) {
					log.debug("Item is a normal form field");
					List<String> values = params.get(itemFieldName);
					if (null == values) {
						values = new ArrayList<String>();
					}

					String charset = servletRequest.getCharacterEncoding();
					if (null == charset) {
						values.add(fileItem.getString());
					} else {
						values.add(fileItem.getString(charset));
					}

					params.put(itemFieldName, values);
					fileItem.delete();
				} else {
					log.debug("Item is a file upload");

					// Skip file uploads that don't have a file name - meaning
					// that no file was selected.
					if (null == fileItem.getName()
							|| fileItem.getName().trim().length() < 1) {
						log.debug("No file has been uploaded for the field: "
								+ itemFieldName);
						continue;
					}

					List<FileItem> values = files.get(itemFieldName);
					if (null == values) {
						values = new ArrayList<FileItem>();
					}

					if (fileItem.isInMemory()) {
						try {
							fileItem.write(((DiskFileItem) fileItem).getStoreLocation());
						} catch (Exception e) {
							log.warn("Unable to write item", e);
							errors.add(e.getMessage());
						}

					}
					values.add(fileItem);
					files.put(itemFieldName, values);
				}
			}
		} catch (FileUploadException e) {
			log.warn("Unable to parse request", e);
			errors.add(e.getMessage());
		}
	}

	private RequestContext createRequestContext(final HttpServletRequest req) {
		return new RequestContext() {
			public String getCharacterEncoding() {
				return req.getCharacterEncoding();
			}

			public String getContentType() {
				return req.getContentType();
			}

			public int getContentLength() {
				return req.getContentLength();
			}

			public InputStream getInputStream() throws IOException {
				InputStream inputStream = req.getInputStream();
				if (inputStream == null) {
					throw new IOException("Missing content in the request");
				}
				return req.getInputStream();
			}
		};
	}

}
